#ifndef GRAPHICS_DX_H
#define GRAPHICS_DX_H

#include "game.h"
#include "obstacle.h"
#include "lib3dexport.h"
#include "graphicsInterface.h"

#include <DXUT.h>
#include <DXUTmisc.h>
#include <list>

namespace Lib3D {

class LIB3D_API Graphics : public GraphicsInterface {
public:
	Graphics(Level & game, HINSTANCE hInstance, int nCmdShow);
	~Graphics();
	
	bool init(unsigned long shaderFlags);
	void destroy();
	void resize();

	virtual double GetTotalTime();
	virtual double GetDeltaTime();
	virtual void Draw();
	virtual void NextFrame();

	virtual void DrawPoint(float x, float y, float z) {}
	virtual void DrawLine(float x1, float y1, float z1, float x2, float y2, float z2) {}

	static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
	LRESULT CALLBACK WndProc(UINT message, WPARAM wParam, LPARAM lParam);

private:
#pragma warning(push)
#pragma warning(disable:4251)

	HWND hWnd;

	Level & game;
	bool running;
	double time, previousTime, beginningTime;
	std::list<Obstacle*> croppedObstacles;

	HINSTANCE               g_hInst;
	HWND                    g_hWnd;
	D3D10_DRIVER_TYPE       g_driverType;
	ID3D10Device*           g_pd3dDevice;
	IDXGISwapChain*         g_pSwapChain;
	ID3D10RenderTargetView* g_pRenderTargetView;

	ID3D10Device * d3dDevice;

	D3DXMATRIX viewMatrix;
	D3DXMATRIX projectionMatrix;

	// Hall
	struct HallVertex
	{
		D3DXVECTOR3 pos;
		D3DXVECTOR3 normal;
	};

	bool initHall(unsigned long shaderFlags);
	void drawHall();
	
	D3DXMATRIX hallWorldMatrix;

	D3DXVECTOR4 hallMeshColor;

	ID3D10Effect * hallEffect;
	ID3D10InputLayout * hallVertexLayout;
	ID3D10EffectTechnique * hallRenderTechnique;
	ID3D10Buffer * hallVertexBuffer;
	ID3D10Buffer * hallIndexBuffer;
	ID3D10EffectMatrixVariable * hallWorldVariable;
	ID3D10EffectMatrixVariable * hallViewVariable;
	ID3D10EffectMatrixVariable * hallProjectionVariable;
	ID3D10EffectVectorVariable * hallMeshColorVariable;
	ID3D10EffectVectorVariable * hallLightPosVariable;
	ID3D10EffectVectorVariable * hallLightColorVariable;


	// Obstacles
	struct ObstacleVertex
	{
		D3DXVECTOR3 pos;
	};

	bool initObstacle(unsigned long shaderFlags);
	void drawObstacles();
	
	D3DXMATRIX obstacleWorldMatrix;

	D3DXVECTOR4 obstacleMeshColor;

	ID3D10Effect * obstacleEffect;
	ID3D10InputLayout * obstacleVertexLayout;
	ID3D10EffectTechnique * obstacleRenderTechnique;
	ID3D10Buffer * obstacleVertexBuffer;
	ID3D10Buffer * obstacleIndexBuffer;
	ID3D10Buffer * horizontalObstacleVertexBuffer;
	ID3D10Buffer * horizontalObstacleIndexBuffer;
	ID3D10EffectMatrixVariable * obstacleWorldVariable;
	ID3D10EffectMatrixVariable * obstacleViewVariable;
	ID3D10EffectMatrixVariable * obstacleProjectionVariable;
	ID3D10EffectVectorVariable * obstacleMeshColorVariable;
	ID3D10EffectVectorVariable * obstacleLightPosVariable;

	// Light
	D3DXVECTOR4 lightPos;
	D3DXVECTOR4 lightColor;

#pragma warning(pop)
};

}

#endif // GRAPHICS_DX_H
